package com.heng.ReadWriteLockDemo;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

//读写锁，写onlyOne  读，达到多个的目的！
//读没有完成的时候，不能写
class MyResource2{
    Map<String,String> map = new HashMap<>();
    //
    Lock lock = new ReentrantLock();
    //
    ReadWriteLock rwLock = new ReentrantReadWriteLock();

    public void write(String key,String value) {
        rwLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+"\t正在写入");
            map.put(key, value);
            try{TimeUnit.MILLISECONDS.sleep(500);}catch (InterruptedException e) {e.printStackTrace();}
            System.out.println(Thread.currentThread().getName()+"\t完成写入");
        }finally {
            rwLock.writeLock().unlock();
        }
    }

    public void read(String key) {
        rwLock.readLock().lock();
        try{
            System.out.println(Thread.currentThread().getName()+"\t正在读取");
            String result = map.get(key);
            try{TimeUnit.MILLISECONDS.sleep(500);}catch (InterruptedException e) {e.printStackTrace();}
            System.out.println(Thread.currentThread().getName()+"\t完成读取: "+result);
        }finally {
            rwLock.readLock().unlock();
        }
    }
}

public class ReentrantRWLockDemo2 {
    public static void main(String[] args) {
        MyResource2 myResource = new MyResource2();
        for(int i = 1;i <= 10 ;i++) {
            int finalI = i;
            new Thread(()->{
                myResource.write(finalI+"",finalI+"");
            },String.valueOf(i)).start();
        }

        for(int i = 1;i <= 10 ;i++) {
            int finalI = i;
            new Thread(()->{
                myResource.read(finalI+"");
            },String.valueOf(i)).start();
        }

        for(int i = 1;i <= 10 ;i++) {
            int finalI = i;
            new Thread(()->{
                myResource.write(finalI+"",finalI+"");
            },"新的写锁->"+String.valueOf(i)).start();
        }
    }
}
